雖然鐵人賽已經來到倒數第二天了,
但對我來說還沒有真的要結束的感覺XD
因為這個隱挑戰看起來沒辦法趕在明天完成Q_Q
但我覺得開始了草草結束它有點可惜,
所以明天過後我應該還是會繼續寫下去XD
(PS. 今天有大大跟我說我才知道 Day30 過後還是可以 Day31, 32... 這樣寫下去XD)
可能忙了又忙 可能寫了又寫 可能無數咖啡 在夜晚嚐了又嚐
可是換來成長 可是換來希望 相信有天你站在台上。
今天的 slogan 一樣很喜歡,所以還是放在文章的開頭處勉勵自己一下XD
有鑑於昨天的 code 真的寫得有夠亂,
我覺得應該要重新整理一下思緒,
重寫一下比較對得起自己的良心(?),
所幸在開始隱挑戰的時候我就已經有用 GitHub 在做版控,
所以我要將版本復原到前天的版本。
切換分支:git checkout 分支名稱
輕輕鬆鬆就回到前天的版本:D
檢討一下昨天比較有問題的地方:
試著再剖析一下整個回合的程序,應該是:
男選動作→女選動作→男攻擊→女攻擊→怪攻擊
栽在動作先後順序上,
是因為選動作是有鍵盤監聽事件的,
在按下鍵盤按鍵之後才會有後續動作
所以很好控制先後順序。
但選動作之後的攻擊是沒有鍵盤事件的,
會一連串跑完,
所以這邊只能用函數控制先後順序。
我把昨天的進度抄到選擇動作的地方,
這次要試著在 男攻擊→女攻擊 中間有延遲的效果,
終於找到救星:setTimeout(函數,延遲毫秒數),
為了試延遲效果,
先在 JavaScript 這樣寫:
currentActor = 0;
setTimeout(roleActionExecute, 1000);
function roleActionExecute(){
console.log(`${new Date()}`);
console.log(`開始執行動作,現在輪到 ${roleStatus[currentActor].Name}`);
console.log(`${roleStatus[currentActor].Name} 選擇的動作是 ${roleStatus[currentActor].Action.OptionSelection}`);
currentActor ++;
if ( currentActor < 2 ){
setTimeout(roleActionExecute, 2000);
}
}
太好了,李逍遙攻擊後有延遲 2 秒才換趙靈兒攻擊!
這邊再加上扣掉怪的血量 console.log 看一下吧:
function roleActionExecute(){
console.log(`${new Date()}`);
console.log(`開始執行動作,現在輪到 ${roleStatus[currentActor].Name}`);
console.log(`${roleStatus[currentActor].Name} 選擇的動作是 ${roleStatus[currentActor].Action.OptionSelection}`);
switch(roleStatus[currentActor].Action.OptionSelection){
case "attack": // 動作為攻擊
let attackQty = roleStatus[currentActor].AttackPower - roleStatus[2].DefensePower;
roleStatus[2].HealthPoint[0] -= attackQty;
console.log(`現在 ${roleStatus[2].Name} 的血量為 ${roleStatus[2].HealthPoint[0]}`);
break;
default:
console.log("default");
break;
}
currentActor ++;
if ( currentActor < 2 ){
setTimeout(roleActionExecute, 2000);
}
}
看起來 OK 之後,再讓我們把扣血的顯示加回去吧!
這邊就可以用 setTimeout(函數,延遲毫秒數) 輕鬆達到延遲的效果。
function roleActionExecute(){
console.log(`${new Date()}`);
console.log(`開始執行動作,現在輪到 ${roleStatus[currentActor].Name}`);
console.log(`${roleStatus[currentActor].Name} 選擇的動作是 ${roleStatus[currentActor].Action.OptionSelection}`);
if ( currentActor < 2 ){
switch(roleStatus[currentActor].Action.OptionSelection){
case "attack": // 動作為攻擊
let attackQty = roleStatus[currentActor].AttackPower - roleStatus[2].DefensePower;
roleStatus[2].HealthPoint[0] -= attackQty;
monsterBloodMinusElement.textContent = `-${attackQty}`;
console.log(`現在 ${roleStatus[2].Name} 的血量為 ${roleStatus[2].HealthPoint[0]}`);
let newClass = `${originClass} animate__animated animate__flash`;
monsterBloodMinusElement.setAttribute("class",newClass);
setTimeout(bloodClassReset, 2000); // 延遲2秒才將 Animate 的 class 拿掉
break;
default:
console.log("default");
break;
}
// 如果怪的血量 <= 0,表示怪被消滅了,後續動作不用執行
if ( roleStatus[2].HealthPoint[0] <=0 ){
console.log("戰鬥勝利");
} else{
currentActor ++;
setTimeout(roleActionExecute, 3000); // 延遲 3 秒再執行一次角色執行動作
}
} else{
console.log("輪到怪");
}
}
function bloodClassReset(){
console.log(`${new Date()}`);
console.log("清空 Animate.css 的 class");
monsterBloodMinusElement.textContent = "";
monsterBloodMinusElement.setAttribute("class",originClass);
}
而且我是將角色執行動作都寫在同一個函數之中,
只是用 setTimeout(roleActionExecute, 3000) 等待 3 秒才換下一個角色動作這樣。
血條的顯示就跟昨天一樣,
就不贅述XD
不過寫到這邊好開心啊,
因為我總算是改變昨天一個角色一個函數的寫法,
讓我回想起 Day20 的挑戰,也是到 Day21 改變寫法XD
首先在 roleActionExecute() 裡面寫主角扣血(先寫死固定攻擊趙靈兒),
在趙靈兒被怪攻擊時血量也會加上閃爍的動畫,
再來 bloodClassReset() 會將趙靈兒的血條回復成原本的 class,
一定要 reset 成原本的 class,
因為 Animate.css 所加的 CSS class 要在加的當下才會有動畫,
動畫結束之後則靜止不動,
所以要將為了動畫所加的 class 清掉,
下次要顯示動畫時再加一次 class。
另外還要判斷怪的血是否 >0,
是的話則將 currentActor 設回 0,(0:李逍遙 1:趙靈兒 2:怪)
再執行主角選動作的函數 roleActionSelect()。
function roleActionExecute(){
if ( currentActor < 2 ){
... 中略 ...
} else{
console.log("輪到怪");
let attackQty = roleStatus[currentActor].AttackPower - roleStatus[1].DefensePower;
roleStatus[1].HealthPoint[0] -= attackQty;
console.log(`現在 ${roleStatus[1].Name} 的血量為 ${roleStatus[1].HealthPoint[0]}`);
girlStatusElement.innerHTML = `<p class="HP">${roleStatus[1].HealthPoint[0]}/${roleStatus[1].HealthPoint[1]}</p>`;
girlStatusElement.innerHTML += `<p class="MP">${roleStatus[1].MagicPoint[0]}/${roleStatus[1].MagicPoint[1]}</p>`;
// originClass = girlStatusElement.getAttribute("class");
originClass = girlStatusElement.childNodes[0].getAttribute("class");
console.log(`原本的 class: ${originClass}`);
newClass = `${originClass} active animate__animated animate__flash`;
girlStatusElement.childNodes[0].setAttribute("class",newClass);
setTimeout(bloodClassReset, 2000); // 延遲2秒才將 Animate 的 class 拿掉
}
}
function bloodClassReset(){
if ( currentActor < 2 ){
monsterBloodMinusElement.textContent = "";
monsterBloodMinusElement.setAttribute("class",originClass);
currentActor ++;
} else{
girlStatusElement.childNodes[0].setAttribute("class",originClass);
// 如果怪的血量 > 0 則要繼續戰鬥
if ( roleStatus[2].HealthPoint[0] >0 ){
currentActor = 0; // 0:李逍遙 1:趙靈兒 2:怪 與roleStatus順序一致
roleActionSelect();
}
}
}
終於寫完整個回合制了!!!!!
開心!
因為招式顯示應該也會花不少時間,
為了明天團隊的完賽,
明天進度暫定為箭頭顯示好了XD
我說的是輪到誰選擇動作時,
頭上會有箭頭顯示,如下方紅框所示↓
但因為我沒有把兩位主角特別切出來,
所以我會把箭頭做在右下角角色狀態那裡。